﻿package media;


import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.Hashtable;

import javax.imageio.ImageIO;

import core.Man;
import core.Mess;


//========================================================= Управление ресурсами
/**
 * Содержит информацию об используемых медиа-ресурсах. <br />
 * Управляет: <br />
 * - загрузкой и выгрузкой ресурсов; <br />
 * - помещением ресурсов в кеш и извлечением из него. <br />
 */
public final class ResMan {

//==================================================================== Константы
public static final char CHAR = '#'; // Символ начала ресурса
public static final int MAX_RES = 128; // максимальное кол-во хранимых в памяти ресурсов
public static final Long UNK_RES_NUM = new Long(0); // Номер ресурса "неизвестный ресурс"


//=================================================================== Переменные
private InputStream data;

public Hashtable<Long, Resource> res = new Hashtable<Long, Resource>(MAX_RES); // Все ресурсы

public int smlMaxW; // Максимальная ширина смайлов
public int smlMaxH; // Максимальная высота


// =============================================================== Инициализация
public ResMan() {

	Mess.m("ResMan.init", "=====");
	loadSmiles();
}


// ================================================= Загрузить картинку из файла
public static BufferedImage loadImage(int imgType, String resource) {

	BufferedImage img = null;

	try {
		URL u;
		switch (imgType) {
			case Resource.RES_SML_STATIC:
				u = Man.main.getClass().getResource("/res/s/" + resource + ".png");
				img = ImageIO.read(u);
				break;
			case Resource.RES_SML_ANI:
				u = Man.main.getClass().getResource("/res/a/" + resource + ".png");
				img = ImageIO.read(u);
				break;
		}

	} catch (Exception e) {
		Mess.err("ResMan.getImgFile", "Не могу загрузить картинку: type=" + imgType
				+ ", resource=" + resource + ".png", e);
	}

	return img;
}


// ============================================================ Загрузка смайлов
public void loadSmiles() {

	try {

		data = this.getClass().getResourceAsStream("/res/sml.txt");

		int id;

		do {

			// Ищем знак начала смайла (#)
			do {
			} while (data.read() != '#');

			// Набор символов отображения смайла
			id = readInt();
			//			Mess.m("SmileList.loadSmiles", "sym=" + sym);

			Pic p = new Pic();
			p.setID(0, id);

			p.alt = readString();
			String file = readString();

			// Анимация
			if (data.read() == ' ') { // Смайл анимирован

				p.type = Resource.RES_SML_ANI;
				p.img = loadImage(Resource.RES_SML_ANI, file);

				p.w = readInt();
				p.h = readInt();

				// Кадры и длительность

				// Количество кадров
				int frameNum = readInt();
				p.seq = new byte[frameNum << 1];

				// Кадры
				for (int q = 0; q < frameNum; ++q) {
					p.seq[q << 1] = (byte) readInt(); // Номер кадра
					p.seq[(q << 1) + 1] = (byte) readInt(); // Длительность
				}

			} else { // Смайл статичный
				p.img = loadImage(Resource.RES_SML_STATIC, file);
				p.w = p.img.getWidth();
				p.h = p.img.getHeight();
			}

			if (id == 0) { // Смайл служебный, для неизвестных смайлов
				p.type = Resource.RES_SML_UNK;
			}

			res.put(p.id, p);

			if (p.w > smlMaxW) {
				smlMaxW = p.w;
			}
			if (p.w > smlMaxH) {
				smlMaxH = p.w;
			}

		} while (id != 0);

		data.close();

		Mess.m("ResMan.loadSmiles", "smlMaxW=" + smlMaxW + ", smlMaxH=" + smlMaxH);

	} catch (Exception e) {
		Mess.err("ResMan.loadSmiles", "Ошибка чтения смайлов", e);
	}

}


// ============================================================== Прочесть число
private int readInt() throws IOException {

	int ret = 0;
	char ch;

	// Пропускаем не числа
	while (!((ch = (char) data.read()) >= '0' && ch <= '9'))
		;

	do {
		ret = (ret << 3) + ret + ret + ch - 0x30;
	} while ((ch = (char) data.read()) >= '0' && ch <= '9');

	return ret;
}


// ============================================================== Прочесть слово
private String readString() {

	char ch;
	StringBuffer textBuf = new StringBuffer(12);

	try {
		// Пропускаем пустоту
		while ((ch = (char) data.read()) <= ' ')
			;

		textBuf.append(ch);

		// Текстовое описание
		while ((ch = (char) data.read()) > ' ') {
			textBuf.append(ch);
		}

	} catch (IOException e) {
		Mess.err("SmileList.readString", "Ошибка чтения строки", e);
	}

	return textBuf.toString();

}


//========================================================== Выдать ресурс по ID
public Resource getRes(Long id) {

	Resource res = (Resource) this.res.get(id);
	if (res != null) {
		return res;
	} else {
		return (Resource) this.res.get(UNK_RES_NUM);
	}

}


//=========================================================== Выдать все ресурсы
public Enumeration<Resource> getAll() {

	return this.res.elements();
}


//=========================================================== Выдать все ресурсы
public int getLen() {

	return this.res.size();
}


}
